package com.elitel.common.businessJdbc;

import java.util.Map;

import com.elitel.frame.main.entity.constant.DictionaryConstant;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;

// here using sql injection for insert statement
// how to construct sql statement
// common method getPrecompileSql , get type by columnName
@Data
@Slf4j
public class BusinessInsertPreparedStatement extends AbstractBusinessPreparedStatement{
    private String tableName;
    private Map<String, String> columnNameMap;
    private Map<String, Object> columnValueMap;
    private Map<String, String> fieldTypeMap;

    private static final String sqlPlaceHolder = "?";

    public static Builder builder(){
        return new Builder(DictionaryConstant.DatabaseType_MYSQL);
    }

    public static Builder builder(String databaseType){
        return new Builder(databaseType);
    }

    @Override
    public String getPrecompileSql(){
        StringBuilder sb = new StringBuilder();
        sb.append(" insert into  ")
            .append(getTableName())
            .append(" ( ")
            .append(getColumnNameList())
            .append(" ) values ( ")
            .append(getColumnValuePlaceHolderList())
            .append(")");
        log.info("insert precompile sql: " + sb.toString());
        return sb.toString();
    }

    private String getColumnNameList(){
        StringBuilder sb = new StringBuilder();
        columnNameMap.forEach((columnName, strColumnName) -> {
                if(sb.length() == 0){
                    sb.append(strColumnName);
                    return ;
                }
                sb.append(", ").append(strColumnName);
            });
        return sb.toString();
    }

    private String getColumnValuePlaceHolderList(){
        StringBuilder sb = new StringBuilder();
        columnNameMap.forEach((columnName, strColumnName) -> {
                if(sb.length() == 0){
                    sb.append(sqlPlaceHolder);
                    return ;
                }
                sb.append(", ").append(sqlPlaceHolder);
            });
        return sb.toString();
    }

    public static class Builder{
        private String serviceGuid;
        private String tableName;
        private String databaseType;
        private Map<String, String> columnNameMap;
        private Map<String, Object> columnValueMap;
        private Map<String, String> fieldTypeMap;

        public Builder(String databaseType){
            this.databaseType = databaseType;
        }

        public Builder serviceGuid(String serviceGuid){
            this.serviceGuid = serviceGuid;
            return this;
        }

        public Builder tableName(String tableName){
            this.tableName = tableName;
            return this;
        }

        public Builder columnNameMap(Map<String, String> columnNameMap){
            this.columnNameMap = columnNameMap;
            return this;
        }

        public Builder columnValueMap(Map<String, Object> columnValueMap){
            this.columnValueMap = columnValueMap;
            return this;
        }

        public Builder fieldTypeMap(Map<String, String> fieldTypeMap){
            this.fieldTypeMap = fieldTypeMap;
            return this;
        }

        public BusinessInsertPreparedStatement build(){
            BusinessInsertPreparedStatement bps = new BusinessInsertPreparedStatement();
            bps.setDatabaseType(databaseType);
            bps.setServiceGuid(serviceGuid);
            bps.setTableName(tableName);
            bps.setColumnNameMap(columnNameMap);
            bps.setColumnValueMap(columnValueMap);
            bps.setFieldTypeMap(fieldTypeMap);
            return bps;
        }
    }
}
